#include "StdAfx.h"
#include "Sketch.h"
#include "VectorSketch.h"
#include "Picture.h"

Sketch::Sketch()
	: mVectorSketch(0),
	  mSavedVectorParameters(kNumberOfVectorParameters)
{}

Sketch::~Sketch()
{
	delete mVectorSketch;
}

BOOL Sketch::SaveOutlinesTo(const TCHAR* inPath, int inIndex) const
{
	if (NULL == mVectorSketch || NULL == inPath ||
		0 >= inIndex || kBiggestIndexOfSaveTo < inIndex)
	{
		return false;
	}

	if (kIndexSaveToMetafile == inIndex)
	{
		return mVectorSketch->SaveToMetafile(inPath);
	}

	HANDLE hFile = ::CreateFile(inPath, GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
	if (INVALID_HANDLE_VALUE == hFile)
	{
		return false;
	}

	bool result = false;

	std::ostringstream outputStream;
	switch (inIndex)
	{
	case kIndexSaveToSVG:
		result = mVectorSketch->SaveToSVG(outputStream);
		break;
	case kIndexSaveToVML:
		result = mVectorSketch->SaveToVML(outputStream);
		break;
	case kIndexSaveToPDF:
		result = mVectorSketch->SaveToPDF(outputStream);
		break;
	}

	result &= outputStream.good();
	if (result)
	{
		std::string stringData = outputStream.str();
		DWORD bytesCount = stringData.length();

		DWORD bytesWritten;
		result = ::WriteFile(hFile, stringData.data(), 
			bytesCount, &bytesWritten, NULL)
			&& bytesWritten == bytesCount;
	}
	::CloseHandle(hFile);
	return result;
}

void Sketch::DrawSketch(const Picture& pic, HDC ioHdc, const RECT& inRect) const
{	
	if (NULL != mVectorSketch)
	{
		POINT vo;
		::GetViewportOrgEx(ioHdc, &vo);
		::SetMapMode(ioHdc, MM_ANISOTROPIC);
		::SetViewportExtEx(ioHdc, 1, -1, 0);		
		::SetViewportOrgEx(ioHdc, vo.x, pic.GetHeight() - 1 + vo.y, NULL);

		float shiftX = 0, shiftY = 0;
		pic.GetDotShift(shiftX, shiftY);
		mVectorSketch->Draw(ioHdc, inRect, pic.GetScale(), shiftX, shiftY);
	}
}

bool Sketch::HighlightStroke(const Picture& pic, int inX, int inY, RECT& outRect)
{
	if (NULL == mVectorSketch)
		return false;
	RECT r;
	float shiftX, shiftY;
	pic.GetDotShift(shiftX, shiftY);
	float mScale = pic.GetScale();
	float x = float(inX) / mScale - shiftX;
	int mHeight = pic.GetRawHeight();
	float y = mHeight - inY / mScale - shiftY;

	float hitAreaEnlargement = 1.0f; // several pixels
	if (mVectorSketch->HighlightStroke(x, y, hitAreaEnlargement / mScale, r))
	{
		outRect.left = LONG(mScale * r.left);
		outRect.right = LONG(mScale * r.right);
		outRect.top = LONG(mScale * (mHeight - 1 - r.bottom));
		outRect.bottom = LONG(mScale * (mHeight - 1 - r.top));
		return true;
	}
	return false;
}

void Sketch::SetVectorParameter(int inKey, bool inValue)
{
	if (mSavedVectorParameters.size() > (unsigned) inKey)
	{
		mSavedVectorParameters[inKey] = inValue;
		if (NULL != mVectorSketch)
		{
			mVectorSketch->SetParameter(inKey, inValue);
		}
	}
}

bool Sketch::IsDrawingAllStrokes() const
{
	return NULL != mVectorSketch && 
		mVectorSketch->IsDrawingAllStrokes();
}

bool Sketch::CanSaveOutlines() const
{
	return  (NULL != mVectorSketch && mVectorSketch->IsFinal());
}

void Sketch::Set(int mWidth, int mHeight)
{
	mVectorSketch = new VectorSketch(float(mWidth), float(mHeight));
	for (size_t key = 0; key < mSavedVectorParameters.size(); ++key)
	{
		mVectorSketch->SetParameter(key, mSavedVectorParameters[key]);
	}
}

VectorSketch& Sketch::GetVectorSketch()
{
	return *mVectorSketch;
}

const std::wstring Sketch::GetStatisticsText() const
{
	std::wostringstream s;
	if (NULL != mVectorSketch && mVectorSketch->IsFinal())
	{
		mVectorSketch->GetStatistics(s);
	}
	else
	{
		s << "No data";
	}
	return s.str();
}

const std::wstring Sketch::GetHighlightedInfo() const
{
	std::wostringstream s;
	if (NULL != mVectorSketch && mVectorSketch->IsFinal())
	{
		mVectorSketch->GetHighlightedInfo(s);
	}
	return s.str();
}

void Sketch::ResetSketch()
{
	delete mVectorSketch;
	mVectorSketch = 0;
}
